package com.zkthink.ceres.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zkthink.base.R;
import com.zkthink.base.request.PageParams;
import com.zkthink.base.service.SuperServiceImpl;
import com.zkthink.cache.repository.RedisRepositoryImpl;
import com.zkthink.ceres.common.enums.StoreDailyStatisticEnum;
import com.zkthink.ceres.member.dao.MemberMapper;
import com.zkthink.ceres.member.entity.Member;
import com.zkthink.ceres.store.dao.*;
import com.zkthink.ceres.store.dto.*;
import com.zkthink.ceres.store.entity.*;
import com.zkthink.ceres.store.service.StoreService;
import com.zkthink.ceres.store.vo.StoreShowVO;
import com.zkthink.context.BaseContextHandler;
import com.zkthink.database.mybatis.conditions.Wraps;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.*;

import static com.zkthink.ceres.common.constant.CacheKey.buildStorePointKey;

/**
 * <p>
 * 业务实现类 店铺表
 * </p>
 *
 * @author kellen
 * @date 2020-05-14
 */
@Slf4j
@Service
@AllArgsConstructor
public class StoreServiceImpl extends SuperServiceImpl<StoreMapper, Store> implements StoreService {

    private RedisRepositoryImpl redisRepository;
    @Autowired
    private StoreMemberMapper storeMemberMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private StoreProjectMapper storeProjectMapper;
    @Autowired
    private StoreJoinMapper storeJoinMapper;

    @Autowired
    private AppletWithdrawMapper appletWithdrawMapper;


    public static final long STORE_POINT_EXPIRE_TIME = 8 * 3600 * 48;


    @Override
    public Store fidMid(Long mid) {
        return baseMapper.myScore(2, mid);
    }

    @Override
    public IPage<Store> IPageStore(PageParams<Store> page) {
        return baseMapper.IPageStore(page.getPage(), page.getModel());
    }

    @Override
    public Store getDefaultStore() {
        return this.getOne(Wraps.lbQ());
    }

    @Override
    public Store findByTenantCode(String tenantCode) {
        return this.getBaseMapper().findByTenantCode(tenantCode);
    }


    @Override
    public void addStorePoint(Long storeId, StoreDailyStatisticEnum statisticEnum) {
        redisRepository.incr(buildStorePointKey(statisticEnum, storeId), STORE_POINT_EXPIRE_TIME);
    }

    @Override
    public void addStorePoint(List<Long> storeIds, StoreDailyStatisticEnum statisticEnum) {
        storeIds.forEach(
                e -> redisRepository.incr(buildStorePointKey(statisticEnum, e), STORE_POINT_EXPIRE_TIME));
    }

    @Override
    public IPage<Store> findStoreListForPlatform(PageParams<StorePageDTO> params) {
        IPage<Store> page = params.getPage();
        List<Store> storeList = baseMapper.findStoreListIgnoreTenant((page.getCurrent() - 1) * page.getSize(), page.getSize());
        int total = baseMapper.findStoreListIgnoreTenantCount();
        page.setRecords(storeList);
        page.setTotal(total);
        return page;
    }

    @Override
    public String findTenantCodeByStoreId(Long storeId) {
        return baseMapper.findTenantCodeByStoreId(storeId);
    }

    /**
     * 添加核销人员
     *
     * @return
     */
    @Transactional
    @Override
    public R addverify(AddverifyDto dto) {
        Member members = memberMapper.selectByPhone(dto.getPhone());
        if (members == null) {
            return R.fail("该人员不能添加（店长、其他店核销人员）");
        }
        StoreMember byMid = storeMemberMapper.findByMid(members.getId(), dto.getStoreId());
        if (byMid != null) {
            return R.fail("已有该核销人员");
        }
        StoreMember storeMember = new StoreMember();
        storeMember.setUserType(3);
        storeMember.setMid(members.getId());
        storeMember.setStoreId(dto.getStoreId());
        storeMemberMapper.insert(storeMember);
        memberMapper.updateUserType(members.getId(), 3);
        return R.success();
    }

    @Override
    public R appletWithdraw(AppletWithdraw appletWithdraw) {
        AppletWithdraw mid = appletWithdrawMapper.selectOne(new QueryWrapper<AppletWithdraw>().eq("mid", appletWithdraw.getMid()).eq("applyStatus", 0));
        if (mid != null){
            return R.fail("请勿重复申请");
        }
        appletWithdraw.setMid(BaseContextHandler.getUserId());
        return appletWithdrawMapper.insert(appletWithdraw) > 0 ? R.success("提现已发起") : R.fail("新增失败");
    }

    @Override
    public R<IPage<AppletWithdraw>> findWithdrawHis(IPage page, AppletWithdraw model) {
        IPage<AppletWithdraw> withdrawHis = appletWithdrawMapper.findWithdrawHis(page, model);
        if (withdrawHis.getSize() == 0){
            return R.fail("暂无数据");
        }
        return R.success(withdrawHis);
    }

    /**
     * 删除核销人员
     *
     * @param mid
     * @return
     */
    @Transactional
    @Override
    public R deleteVerify(Long mid) {
        storeMemberMapper.deleteByMid(mid);
        memberMapper.updateUserType(mid, 1);
        return R.success();
    }

    /**
     * 查找核销人员
     *
     * @return
     */
    @Override
    public R verify(Long storeId) {
        return R.success(storeMemberMapper.verify(storeId));
    }

    /**
     * 店铺展示
     *
     * @param dto
     * @return
     */
    @Override
    public List<StoreShowVO> allStore(AllStoreDTO dto) {
        List<StoreShowVO> storeShowVOS2 = new ArrayList<>();
        List<StoreShowVO> storeShowVOS = null;
        if (dto.getState() == 1) {
            storeShowVOS = baseMapper.allStore(dto);
        } else {
            storeShowVOS = baseMapper.allStoreScore(dto);
        }
        if (storeShowVOS == null) {
            return storeShowVOS;
        }
        for (StoreShowVO storeShowVO : storeShowVOS) {
            storeShowVO.setScore(baseMapper.stotrComment(storeShowVO.getId()));
            storeShowVO.setCommentlist(baseMapper.comment(storeShowVO.getId()));
            storeShowVO.setStoreProject(storeProjectMapper.selectBystoreid(storeShowVO.getId()));
        }
        //店铺过期不显示
        for (StoreShowVO storeShowVO : storeShowVOS) {
            if (storeShowVO.getExpirationime() != null) {
                if (storeShowVO.getExpirationime().isAfter(LocalDateTime.now())) {
                    storeShowVOS2.add(storeShowVO);
                }
            }

        }
        storeShowVOS2.sort(Comparator.comparing(StoreShowVO::getScore).reversed());

        return storeShowVOS2;
    }

    /**
     * 店铺展示 评分排序
     *
     * @param dto
     * @return
     */
    @Override
    public List<StoreShowVO> allStoreScore(AllStoreDTO dto) {
        List<StoreShowVO> storeShowVOS = baseMapper.allStoreScore(dto);
        List<StoreShowVO> storeShowVOS2 = new ArrayList<>();
        for (StoreShowVO storeShowVO : storeShowVOS) {
            storeShowVO.setScore(baseMapper.stotrComment(storeShowVO.getId()));
            storeShowVO.setCommentlist(baseMapper.comment(storeShowVO.getId()));
            storeShowVO.setStoreProject(storeProjectMapper.selectBystoreid(storeShowVO.getId()));
        }
        //店铺过期不显示
        for (StoreShowVO storeShowVO : storeShowVOS) {
            if (storeShowVO.getExpirationime() != null) {
                if (storeShowVO.getExpirationime().isAfter(LocalDateTime.now())) {
                    storeShowVOS2.add(storeShowVO);
                }
            }

        }
        storeShowVOS2.sort(Comparator.comparing(StoreShowVO::getScore).reversed());

        return storeShowVOS2;
    }

    /**
     * 店铺展示 评分排序
     *
     * @param dto
     * @return
     */
    @Override
    public List<StoreShowVO> allStoreScoreHuaWei(AllStoreDTO dto) {
        List<StoreShowVO> storeShowVOS = baseMapper.allStoreScoreHuaWei(dto);
        List<StoreShowVO> storeShowVOS2 = new ArrayList<>();
        for (StoreShowVO storeShowVO : storeShowVOS) {
            storeShowVO.setScore(baseMapper.stotrComment(storeShowVO.getId()));
            storeShowVO.setCommentlist(baseMapper.comment(storeShowVO.getId()));
            storeShowVO.setStoreProject(storeProjectMapper.selectBystoreid(storeShowVO.getId()));
        }
        //店铺过期不显示
        for (StoreShowVO storeShowVO : storeShowVOS) {
            if (storeShowVO.getExpirationime() != null) {
                if (storeShowVO.getExpirationime().isAfter(LocalDateTime.now())) {
                    storeShowVOS2.add(storeShowVO);
                }
            }

        }
        storeShowVOS2.sort(Comparator.comparing(StoreShowVO::getScore).reversed());

        return storeShowVOS2;
    }

    public ApplyStoreDto newApplyStoreDtoByStoreJoin(StoreJoin storeJoin) {
        ApplyStoreDto applyStoreDto = new ApplyStoreDto();
        applyStoreDto.setStoreId(storeJoin.getId());
        BeanUtils.copyProperties(storeJoin, applyStoreDto);
        applyStoreDto.setIdImgList(storeJoin.getIdImgs() != null ? storeJoin.getIdImgs().split(",") : null);
        applyStoreDto.setStorefrontImgList(storeJoin.getStorefrontImg() != null ? storeJoin.getStorefrontImg().split(",") : null);
        applyStoreDto.setStoreintroImgList(storeJoin.getStoreintroImg() != null ? storeJoin.getStoreintroImg().split(",") : null);
        return applyStoreDto;
    }

    public ApplyStoreDto newApplyStoreDtoByStore(Store store) {
        ApplyStoreDto applyStoreDto = new ApplyStoreDto();
        applyStoreDto.setStoreId(store.getId());
        BeanUtils.copyProperties(store, applyStoreDto);
        applyStoreDto.setRegisterCity(store.getCity());
        applyStoreDto.setIdImgList(store.getIdImgs() != null ? store.getIdImgs().split(",") : null);
        applyStoreDto.setStorefrontImgList(store.getStorefrontImg() != null ? store.getStorefrontImg().split(",") : null);
        applyStoreDto.setStoreintroImgList(store.getStoreintroImg() != null ? store.getStoreintroImg().split(",") : null);
        return applyStoreDto;
    }

    /**
     * 我的店铺  店长 核销人员
     *
     * @return
     */
    @Override
    public R myScore(Long userid) {
        //身份 1=普通用户 2-商家用户 3-核销人员
        // 1=没有店铺 2=审核中 3=审核失败 请重新申请 4=店铺到期 请续费 5=店铺已删除
        StoreJoin storeJoin = storeJoinMapper.selectOneByMid(userid);//根据店铺查询审核信息,不包含审核失败的
        //StoreMember storeMember = storeMemberMapper.selectByMid(userid);//查询当前登录用户的店铺和身份对应信息
        QueryWrapper<Store> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mid", userid);
        Store store = baseMapper.selectOne(queryWrapper);

        Map<String, Object> map = new HashMap<>();
        // 核销人员登录
        if (store != null) {
            //Store store = baseMapper.selectById(storeMember.getStoreId());//根据身份信息找对应的店铺
            ApplyStoreDto applyStoreDto = newApplyStoreDtoByStore(store);
            if (store.getIsDelete() == 1) {
                //店铺已被删除
                map.put("status", 5);
                map.put("store", applyStoreDto);
                return R.success(map);
            }
            store.setUserType(store.getUserType());
            store.setScore(baseMapper.stotrComment(store.getId()));
            if (store.getApplyType() == 0) {
                // 到期
                map.put("status", 2);
                map.put("store", applyStoreDto);
                return R.success(map);
            } else if (store.getApplyType() == 2) {
                // 到期
                map.put("status", 3);
                map.put("store", applyStoreDto);
                map.put("reason", storeJoin.getReason());//申请失败原因
                return R.success(map);
            } else {
                map.put("status", 0);
                map.put("store", applyStoreDto);
                return R.success(map);
            }
        } else {
            //审核
            if (storeJoin == null) {
                map.put("status", 1);
                map.put("store", null);
                return R.success(map);
            }
            //取消返回审核的状态，设置返回的是审核中的数据;
            ApplyStoreDto applyStoreDto = newApplyStoreDtoByStoreJoin(storeJoin);
            if (storeJoin.getApplyType() == 0) {
                map.put("status", 2);
                map.put("store", applyStoreDto);
                map.put("statusName", "审核中");
                return R.success(map);
            } else if (storeJoin.getApplyType() == 2) {
                map.put("status", 3);
                map.put("store", applyStoreDto);
                map.put("statusName", "申请失败");
                map.put("reason", storeJoin.getReason());//申请失败原因
                return R.success(map);
            }
        }

        map.put("status", 1);
        map.put("store", null);
        return R.success(map);
    }

    /**
     * 店铺添加服务
     *
     * @return
     */
    @Override
    public R addstoreProject(Map<String, Object> vo) {
        StoreProject storeProject = new StoreProject();
        storeProject.setTitle(vo.get("title").toString());
        storeProject.setSubtitle(vo.get("subtitle").toString());
        storeProject.setImg(vo.get("img").toString());
        storeProject.setRemarks(vo.get("remarks").toString());
        storeProject.setPrice(getBigDecimal(vo.get("price")));
        storeProject.setStoreid(Long.valueOf(vo.get("storeid").toString()));
        storeProject.setContent(vo.get("content").toString());
        storeProject.setBackgroundimg(vo.get("backgroundimg").toString());
        storeProjectMapper.insert(storeProject);
        return R.success();
    }

    public static BigDecimal getBigDecimal(Object value) {
        BigDecimal ret = null;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof BigInteger) {
                ret = new BigDecimal((BigInteger) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }

    /**
     * 假删除
     *
     * @param id
     * @return
     */
    @Override
    public R delectstoreProject(Long id) {
        storeProjectMapper.updatedelFlag(id);
        return R.success();
    }

    @Override
    public R storeProject(Long storeid) {

        return R.success(storeProjectMapper.list(storeid));
    }

    /**
     * 获取所以的市
     *
     * @return
     */
    @Override
    public List<String> getcity() {
        return baseMapper.getcity();
    }

    /**
     * 店铺详情
     *
     * @param id
     * @return
     */
    @Override
    public StoreShowVO xianqing(Long id) {
        baseMapper.addFrequency(id);
        StoreShowVO xianqing = baseMapper.xianqing(id);
        xianqing.setScore(baseMapper.stotrComment(id));
        xianqing.setCommentlist(baseMapper.comment(id));
        xianqing.setStoreProject(storeProjectMapper.selectBystoreid(id));
        return xianqing;
    }

    /**
     * 服务详情
     *
     * @param id
     * @return
     */
    @Override
    public StoreProjectXianqing projectXianqing(Long id) {
        StoreProjectXianqing dto = storeProjectMapper.StoreProjectXianqing(id);
        dto.setScore(baseMapper.productComment(id));
        dto.setCommentlist(baseMapper.Projectcomment(id));
        dto.setListImg(dto.getImg().split(","));
        return dto;
    }

    @Override
    public R updateStore(StoreUpdateDTO dto) {
        Store store = baseMapper.selectById(dto.getId());
        BeanUtils.copyProperties(dto, store);
        store.setApplyType(0);
        return R.success(baseMapper.updateById(store));
    }

    @Override
    public R selectstoreid(Long id) {
        Store store = baseMapper.selectById(id);
        Boolean b = true;
        if (store.getIsDelete() == 1) {
            b = false;
        } else if (!store.getExpirationime().isAfter(LocalDateTime.now())) {
            b = false;
        }
        return R.success(b);
    }

}
